package com.baijiayun.live.ui.toolbox.redpacket;

import android.annotation.SuppressLint;
import android.text.TextUtils;

import com.baijiayun.live.ui.activity.LiveRoomRouterListener;
import com.baijiayun.live.ui.toolbox.redpacket.widget.MoveModel;
import com.baijiayun.liveuibase.utils.RxUtils;
import com.baijiayun.livecore.alilog.AliYunLogHelper;
import com.baijiayun.livecore.context.LPConstants;
import com.baijiayun.livecore.context.LPError;
import com.baijiayun.livecore.context.LPException;
import com.baijiayun.livecore.models.LPRedPacketModel;
import com.baijiayun.livecore.models.RedPacketTopList;
import com.baijiayun.livecore.utils.LPJsonUtils;
import com.baijiayun.livecore.utils.LPLogger;
import com.baijiayun.livecore.utils.LPRxUtils;
import com.google.gson.JsonObject;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

/**
 * 红包雨效果
 *
 * @author panzq
 * @date 20190514
 */
public class RedPacketPresenter implements RedPacketContract.Presenter {

    private final String TAG = RedPacketPresenter.class.getSimpleName();

    private final long TIME_RED_PACKET_START = 3;//红包启动倒计时时间/s

    private LiveRoomRouterListener mRouter;
    private RedPacketContract.View mView;

    private Disposable mTimeDisposable;
    private Disposable mRedPacketRain;

    private boolean isRobRedPacket = false;

    private LPRedPacketModel mLPRedPacketModel;

    private CompositeDisposable mCompositeDisposable = new CompositeDisposable();
    private volatile int mScoreAmount = 0;

    private RedPacketTopList mTopList;

    private boolean isStudent = true;
    private LPRedPacketModel model;
    private Disposable disposableOfRankListTimer;
    public static int ROB_COUNT;
    public static int ROB_SUCCESS_COUNT;
    public static int ROB_FAIL_COUNT;
    public static int ROB_FAIL_SENSITIVE_COUNT;
    public static float SENSITIVITY;

    public RedPacketPresenter(RedPacketContract.View view, LPRedPacketModel model) {
        this.mView = view;
        this.model = model;
        ROB_COUNT = ROB_SUCCESS_COUNT = ROB_FAIL_COUNT = ROB_FAIL_SENSITIVE_COUNT = 0;
        SENSITIVITY = model.sensitivity;
    }

    @Override
    public void setRouter(LiveRoomRouterListener liveRoomRouterListener) {
        mRouter = liveRoomRouterListener;
    }

    @SuppressLint("CheckResult")
    @Override
    public void subscribe() {
        // do nothing
    }

    @Override
    public void robRedPacket(MoveModel model) {
        if (mLPRedPacketModel == null) {
            return;
        }
        ROB_COUNT++;
        model.isRob = true;
        //发送抢红包请求
        mCompositeDisposable.add(mRouter.getLiveRoom().requestCloudRobRedPacket(Integer.parseInt(mLPRedPacketModel.id))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(lpShortResult -> {
                    RobRedPacketModel robModel = LPJsonUtils.parseJsonObject((JsonObject) lpShortResult.data, RobRedPacketModel.class);
                    if (robModel.status == 0) {
                        LPLogger.d(TAG, "requestCloudRobRedPacket mScoreAmount=" + mScoreAmount + ", 这次抢到了" + robModel.score_amount);
                        //抢成功
                        mScoreAmount += robModel.score_amount;
                        model.scoreAmount = robModel.score_amount;
                        ROB_SUCCESS_COUNT++;
                    } else {
                        LPLogger.d(TAG, "requestCloudRobRedPacket status!=0 失败");
                        //抢失败
                        model.scoreAmount = 0;
                        ROB_FAIL_COUNT++;
                    }
                    model.isOpen = true;
                }, throwable -> {
                    if (throwable instanceof LPException && ((LPException) throwable).getErrorCode() == LPError.CODE_ERROR_RED_PACKET_LOW_SENSITIVITY) {
                        model.isOpen = true;
                        model.scoreAmount = 0;
                        model.openTime = -1;
                        ROB_FAIL_SENSITIVE_COUNT++;
                    } else {
                        AliYunLogHelper.getInstance().addErrorLog("抢红包报错 : error " + throwable.getMessage());
                    }
                }));
    }

    /**
     * 启动
     */
    @Override
    public void startRedPacket() {
        isStudent = mRouter.getLiveRoom().getCurrentUser().getType() == LPConstants.LPUserType.Student && !mRouter.getLiveRoom().isAudition();
        mView.setRobEnable(isStudent);

        LPLogger.d(TAG, "startRedPacket " + isRobRedPacket);
        if (isRobRedPacket) {
            return;
        }
        release();

        isRobRedPacket = true;
        mTopList = null;
        mLPRedPacketModel = model;
        mTimeDisposable = Observable.interval(0, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    LPLogger.d(TAG, "startRedPacket : time : " + aLong);
                    long timeStart = TIME_RED_PACKET_START - aLong;
                    if (timeStart <= 0) {
                        //倒计时完成，开始抽红包
                        RxUtils.dispose(mTimeDisposable);
                        startRedPacketRain(model);
                    }
                    mView.updateRedPacketTime(timeStart);
                });

        mCompositeDisposable.add(mRouter.getLiveRoom().getObservableOfRedPacketRankList()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(redPacketTopList -> {
                    LPLogger.d(TAG, "getObservableOfRedPacketRankList");
                    mTopList = redPacketTopList;
                }));

        mCompositeDisposable.add(mRouter.getLiveRoom().getObservableOfRedPacketFinish()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(packetId -> {
                    LPLogger.d(TAG, "getObservableOfRedPacketFinish");
                    robFinish(packetId);
                }));
    }

    private void startRedPacketRain(LPRedPacketModel lpRedPacketModel) {
        mScoreAmount = 0;
        mView.switchRedPacketStart(RedPacketContract.TYPE_REDPACKET_RUNNING);
        mRedPacketRain = Observable.interval(0, 1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    LPLogger.d(TAG, "startRedPackRain time : " + aLong);
                    if (aLong >= lpRedPacketModel.duration) {
                        robFinish(lpRedPacketModel.id);
                    }
                });
    }


    private void robFinish(String packetId) {
        LPRxUtils.dispose(disposableOfRankListTimer);
        LPRxUtils.dispose(mRedPacketRain);
        isRobRedPacket = false;
        if (isStudent) {
            if (mScoreAmount <= 0) {
                //显示未抢到提示
                mView.switchRedPacketStart(RedPacketContract.TYE_REDPACKET_NOT_ROB);
            } else {
                //显示抢到总个数
                mView.switchRedPacketStart(RedPacketContract.TYPE_REDPACKET_ROB);
            }
            //等待5秒还未收到排行榜信令则退出
            disposableOfRankListTimer = Observable.timer(5, TimeUnit.SECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(aLong -> {
                        if(mTopList != null){
                            switchState(RedPacketContract.TYPE_REDPACKET_RANKING_LIST);
                        } else{
                            exit(false);
                        }
                    });
        } else{
            mView.switchRedPacketStart(RedPacketContract.TYPE_REDPACKET_ROB_FINISH);
            nowPacketId = packetId;
            if (!TextUtils.isEmpty(nowPacketId) && mRouter.getLiveRoom().getToolBoxVM().enableUseBonusPoints()) {
                mCompositeDisposable.add(mRouter.getLiveRoom().requestCloudRedPacketRankList(Integer.parseInt(nowPacketId))
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(lpShortResult -> {
                            final JsonObject jsonObject = LPJsonUtils.toJsonObject(lpShortResult.data);
                            jsonObject.addProperty("id", nowPacketId);
                            mRouter.getLiveRoom().sendRedPacketRankListBroadcast(jsonObject);
                        }));
            }
        }
    }

    private String nowPacketId = null;

    @Override
    public void showResultList() {
        if (TextUtils.isEmpty(nowPacketId)) {
            return;
        }
        mCompositeDisposable.add(mRouter.getLiveRoom().requestCloudRedPacketRankList(Integer.parseInt(nowPacketId))
                .subscribe(lpShortResult -> {
                    if (lpShortResult == null || !(lpShortResult.data instanceof JsonObject)) {
                        return;
                    }
                    mTopList = LPJsonUtils.parseJsonObject((JsonObject) lpShortResult.data, RedPacketTopList.class);
                    switchState(RedPacketContract.TYPE_REDPACKET_RANKING_LIST);
                }, throwable -> {
                    LPLogger.e(TAG, "requestCloudRedPacketRankList : " + throwable.getMessage());
                    switchState(RedPacketContract.TYPE_REDPACKET_RANKING_LIST);
                }));
    }

    @Override
    public void unSubscribe() {
        // do nothing
    }

    @Override
    public void exit(boolean withRepublish) {
        if (withRepublish) {
            mRouter.onRepublishRedPacket();
        }
        mRouter.switchRedPacketUI(false, null);
    }

    @Override
    public void release() {
        RxUtils.dispose(mTimeDisposable);
        RxUtils.dispose(mRedPacketRain);
        RxUtils.dispose(disposableOfRankListTimer);
        mCompositeDisposable.clear();
        mTimeDisposable = null;
        mRedPacketRain = null;

        isRobRedPacket = false;
        mLPRedPacketModel = null;
    }

    @Override
    public void destroy() {
        release();
        mCompositeDisposable.dispose();
    }

    @Override
    public int getScoreAmount() {
        return mScoreAmount;
    }

    @Override
    public boolean isRobRedPacket() {
        return isRobRedPacket;
    }

    @Override
    public boolean isTeacher() {
        return mRouter != null && mRouter.getLiveRoom().isTeacher();
    }

    @Override
    public void switchState(int type) {
        if (type == RedPacketContract.TYPE_REDPACKET_RANKING_LIST) {
            mView.switchRedPacketRankingList(mTopList == null ? null : mTopList.list);
        } else {
            mView.switchRedPacketStart(type);
        }
    }
}
